﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using MvcEngine.Core;

namespace MvcEngine.Core.Registry
{
    public class ActionFilterRegistry : IActionFilterRegistry
    {
        private readonly List<ActionFilterRecordBase> registry;

        public ActionFilterRegistry()
        {
            registry = new List<ActionFilterRecordBase>();
        }

        public void Clear()
        {
            registry.Clear();
        }

        public void Add(IEnumerable<IFilterCriteria> criteria, Type filterType)
        {
            registry.Add(new ActionFilterTypeRecord(criteria, filterType));
        }

        public void Add(IEnumerable<IFilterCriteria> criteria, object filterObject)
        {
            registry.Add(new ActionFilterObjectRecord(criteria, filterObject));
        }

        public FilterInfo GetFilters(ActionFilterRegistryContext context)
        {
            FilterInfo filters = new FilterInfo();

            foreach (ActionFilterRecordBase record in registry)
            {
                if (record.Match(context))
                {
                    object filterObject = null;

                    if (record is ActionFilterObjectRecord)
                        filterObject = ((ActionFilterObjectRecord)record).Object;
                    if (record is ActionFilterTypeRecord)
                        filterObject = IoC.Resolve(((ActionFilterTypeRecord)record).FilterType);

                    if (filterObject is IActionFilter)
                        filters.ActionFilters.Add((IActionFilter)filterObject);

                    if (filterObject is IAuthorizationFilter)
                        filters.AuthorizationFilters.Add((IAuthorizationFilter)filterObject);

                    if (filterObject is IExceptionFilter)
                        filters.ExceptionFilters.Add((IExceptionFilter)filterObject);

                    if (filterObject is IResultFilter)
                        filters.ResultFilters.Add((IResultFilter)filterObject);
                }
            }

            return filters;
        }
    }
}
